#include "../ZcommonDrv.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#ifdef mcu_stm32f4_hal

/*define an initialization dalay function*/
static void Z_delayInit(void);

static void Z_delayInit(void)
{
    static uint32_t first = 0;

    if (first == 0)
    {
        first = 1;

        HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8);
        /*Disable Systick Counter*/
        SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    }
}

void Z_delay_ms(uint32_t ms)
{
    uint32_t temp = 0;

    Z_delayInit();
    if (!ms)
        return;

    /*if ms inputed is larger than 0.5s, then delay 0.5s every time*/
    while (ms > 500)
    {
        SysTick->LOAD = SystemCoreClock / 8000 * 500;
        SysTick->VAL = 0x000000;
        SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

        do
        {
            temp = SysTick->CTRL;
        } while (temp & 0x01 && !(temp & (1 << 16)));

        SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
        SysTick->VAL = 0x000000;
        ms -= 500;
    }

    SysTick->LOAD = SystemCoreClock / 8000 * ms;
    SysTick->VAL = 0x000000;
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

    do
    {
        temp = SysTick->CTRL;
    } while (temp & 0x01 && !(temp & (1 << 16)));

    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
    SysTick->VAL = 0x000000;
}

void Z_delay_us(uint32_t us)
{
    uint32_t temp = 0;
    uint64_t ms = 0;

    Z_delayInit();

    if (!us)
        return;

    ms = us / 1000;
    us = us % 1000;

    if (ms > 0)
        Z_delay_ms((uint32_t)ms);
    if (us > 0)
    {
        SysTick->LOAD = SystemCoreClock / 8000000 * ms;
        SysTick->VAL = 0x000000;
        SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

        do
        {
            temp = SysTick->CTRL;
        } while (temp & 0x01 && !(temp & (1 << 16)));

        SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
        SysTick->VAL = 0x000000;
    }
}

void Z_delay_s(uint32_t s)
{
    while (s > 0){
        Z_delay_ms(1000);
        s--;
    }
}

void Z_printf(const char *format)
{
    printf(format);
}

uint32_t Z_getms(void)
{
    return HAL_GetTick();
}
#endif